#ifndef _ZBJ_UTILS_H_
#define _ZBJ_UTILS_H_

#include<stdio.h>
#include<regex.h>

#ifdef __cplusplus
extern "C" {
#endif  // __cplusplus

/* report error/debug information */
int report_msg(int retcode, const char* msg);
int report_msg_with_newline(int retcode, const char* msg);

typedef struct _CharBuf {
    char* buf;
    int len;
    int cursor;
    int delta;
} CharBuf;
int init_charbuf(CharBuf* cb, int len, int delta);
int isempty_charbuf(CharBuf* cb);
int append_substr_to_charbuf(CharBuf* cb, const char* src, int start, int end);
int append_str_to_charbuf(CharBuf* cb, const char* src);
int copy_substr_to_charbuf(CharBuf* cb, const char* str, int start, int end);
void clear_charbuf(CharBuf* cb);
void nullterminate_charbuf(CharBuf* cb);
void free_charbuf(CharBuf* cb);

typedef struct _FileContents {
    long file_size;
    char* contents;
} FileContents;
void init_fileContents(FileContents* fc);
int load_file_to_memory(FILE* file, FileContents* fileContent);
void unload_file_from_memory(FileContents* fileContent);

#define NMATCH 10

typedef struct {
    const char* text;
    const char* text_end;
    const char* last_pos;
    int cflags;
    int eflags;
    regex_t regex;
    int nmatch;
    regmatch_t pm[NMATCH+1];
} reg_context;

/* retcode: reg_errcode_t */
int setup_reg_context(reg_context* context, const char* pattern, int cflags, const char* text, int text_len, int eflags);
int regexec_next(reg_context* context);
void destroy_reg_context(reg_context* context);

int reg_match_item_length(reg_context* context, int match_index);

#ifdef __cplusplus
}
#endif // __cplusplus

#endif // _ZBJ_UTILS_H_

